package set

import "sync"

var _ Set[int] = NewSyncSet[int]()

// SyncSet 定义基于 sync.Map 的并发安全的集合
type SyncSet[T comparable] struct {
	elems sync.Map
}

// NewSyncSet 新建一个基于 sync.Map 的并发安全的集合
func NewSyncSet[T comparable](elems ...T) *SyncSet[T] {
	set := &SyncSet[T]{elems: sync.Map{}}
	for _, val := range elems {
		set.elems.Store(val, empty)
	}

	return set
}

// Add 添加元素到集合
func (own *SyncSet[T]) Add(elems ...T) {
	for _, elem := range elems {
		own.elems.Store(elem, empty)
	}
}

// Delete 从集合中删除元素
func (own *SyncSet[T]) Delete(elems ...T) {
	for _, elem := range elems {
		own.elems.Delete(elem)
	}
}

// HasAll 判断所有指定元素是否存在于集合
func (own *SyncSet[T]) HasAll(elems ...T) bool {
	for _, elem := range elems {
		if _, ok := own.elems.Load(elem); !ok {
			return false
		}
	}

	return true
}

// HasAny 判断任一指定元素是存在于集合
func (own *SyncSet[T]) HasAny(elems ...T) bool {
	for _, elem := range elems {
		if _, ok := own.elems.Load(elem); ok {
			return true
		}
	}

	return false
}

// GetLength 获取集合长度
func (own *SyncSet[T]) GetLength() int {
	var length int
	own.elems.Range(func(key, value any) bool {
		length++
		return true
	})

	return length
}

// GetElements 获取集合的所有元素
func (own *SyncSet[T]) GetElements() []T {
	elems := make([]T, 0)
	own.elems.Range(func(key, value any) bool {
		elems = append(elems, key.(T))
		return true
	})

	return elems
}

// GetMap 获取集合的字典格式
func (own *SyncSet[T]) GetMap() map[T]struct{} {
	elems := make(map[T]struct{})
	own.elems.Range(func(key, value any) bool {
		elems[key.(T)] = struct{}{}
		return true
	})

	return elems
}

// IsEmpty 判断集合是否为空
func (own *SyncSet[T]) IsEmpty() bool {
	return own.GetLength() == 0
}

// IsEqualTo 判断两集合的元素是否完全相同
func (own *SyncSet[T]) IsEqualTo(other Set[T]) bool {
	if own.GetLength() != other.GetLength() {
		return false
	}

	return own.IsSubsetOf(other)
}

// IsSubsetOf 判断当前集合是否是指定集合的子集
func (own *SyncSet[T]) IsSubsetOf(other Set[T]) (ok bool) {
	elems := other.GetMap()
	own.elems.Range(func(key, value any) bool {
		if _, ok := elems[key.(T)]; !ok {
			ok = false
			return false
		}

		ok = true
		return true
	})

	return
}

// IsSupersetOf 判断当前集合是否为指定集合的超集
func (own *SyncSet[T]) IsSupersetOf(other Set[T]) bool {
	for _, key := range other.GetElements() {
		if _, ok := own.elems.Load(key); !ok {
			return false
		}
	}

	return true
}

// Unite 求并集（不修改原集合，生成一个新的集合）
func (own *SyncSet[T]) Unite(other Set[T]) Set[T] {
	set := NewSyncSet(other.GetElements()...)
	own.elems.Range(func(key, value any) bool {
		set.Add(key.(T))
		return true
	})
	return set
}

// Intersect 求交集（不修改原集合，生成一个新的集合）
func (own *SyncSet[T]) Intersect(other Set[T]) Set[T] {
	set := NewSyncSet[T]()
	elems := other.GetMap()
	own.elems.Range(func(key, value any) bool {
		elem := key.(T)
		if _, ok := elems[elem]; ok {
			set.Add(elem)
		}

		return true
	})

	return set
}

// Complement 求补集（不修改原集合，生成一个新的集合）
func (own *SyncSet[T]) Complement(other Set[T]) Set[T] {
	set := NewSyncSet[T]()
	elems := other.GetMap()
	own.elems.Range(func(key, value any) bool {
		elem := key.(T)
		if _, ok := elems[elem]; !ok {
			set.Add(elem)
		}

		return true
	})

	for _, elem := range other.GetElements() {
		if _, ok := own.elems.Load(elem); !ok {
			set.Add(elem)
		}
	}

	return set
}

// Range 遍历并获取每个元素
func (own *SyncSet[T]) Range(fn func(T)) {
	own.elems.Range(func(key, value any) bool {
		fn(key.(T))
		return true
	})
}

// Filter 过滤集合，并返回过滤的元素
func (own *SyncSet[T]) Filter(fn func(T) bool) []T {
	elems := make([]T, 0)
	own.elems.Range(func(key, value any) bool {
		elem := key.(T)
		if fn(elem) {
			elems = append(elems, elem)
		}

		return true
	})

	return elems
}

// Clone 克隆当前集合
func (own *SyncSet[T]) Clone() Set[T] {
	return NewUnsafeSet(own.GetElements()...)
}

// Clear 清空集合
func (own *SyncSet[T]) Clear() {
	own.elems = sync.Map{}
}
